﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DevelopAssistant.Service
{
    [Serializable]
    public class ConnectionSection
    {
        public string Key { get; set; }
        public string Value { get; set; }

        public ConnectionSection(string connectionSection)
        {
            string[] list = connectionSection.Split('=');
            this.Key = list[0];
            this.Value = list[1];
        }

    }

    public enum DataBaseLoginStyle
    {
         Integrated_Security=0,
         SqlServer_Identity=1
    }

    [Serializable]
    public class DataBaseServer : ICloneable
    {
        public string ID { get; set; }
        public string Name { get; set; }       
        public string Version { get; set; }
        public string Company { get; set; }
        
        public string ConnectionString { get; set; }
        public string ProviderName { get; set; }
        /// <summary>
        /// 数据文件路径
        /// </summary>
        public string DataFilePath { get; set; }

        public string Server { get; set; }
        public string Instance_Name { get; set; }
        public string Port { get; set; }
        public string DataBaseName { get; set; }
        public DataBaseLoginStyle DataBaseLoginStyle { get; set; }
        public string UserID { get; set; }
        public string Password { get; set; }
        /// <summary>
        /// 是否连接中
        /// </summary>
        public bool OnConnecting { get; set; }

        /// <summary>
        /// 数据表集合
        /// </summary>
        public List<Table> Tables { get; set; }

        /// <summary>
        /// 数据视图集合
        /// </summary>
        public List<View> Views { get; set; }

        /// <summary>
        /// 函数集合
        /// </summary>
        public List<Function> Functions { get; set; }

        /// <summary>
        /// 存储过程集合
        /// </summary>
        public List<Procedure> Procedures { get; set; }

        public List<Keyword> Keywords { get; set; }

        public System.Windows.Forms.TreeNode DataBaseServerNode { get; set; }
        public bool AllObject { get; set; }

        public DataBaseServer()
        {
            this.ID = Guid.NewGuid().ToString();
            this.Tables = new List<Table>();
            this.Views = new List<View>();
            this.Functions = new List<Function>();
            this.Procedures = new List<Procedure>();
            this.DataBaseLoginStyle = DataBaseLoginStyle.SqlServer_Identity;
            this.AllObject = false;
        }

        public DataBaseServer(string ConnectionString, string ProviderName):this()
        {
            this.ConnectionString = ConnectionString;
            this.ProviderName = ProviderName;
            Parse();
        }

        public void Parse()
        {
            if (!String.IsNullOrEmpty(ConnectionString) && !String.IsNullOrEmpty(ProviderName))
            {
                string[] conectionSections = ConnectionString.Split(';');
                Dictionary<string, ConnectionSection> list = new Dictionary<string, ConnectionSection>();
                foreach (string connectionSection in conectionSections)
                {
                    if (!string.IsNullOrEmpty(connectionSection))
                    {
                        ConnectionSection conns = new ConnectionSection(connectionSection);
                        list.Add(conns.Key, conns);
                    }                
                }
                //C:\Users\Administrator\Desktop\Ly.BDF\Ly.BDF\Ly.BDF.WebApp\App_Data\fasdb.db
                string Data_Server = String.Empty;
                switch (ProviderName)
                {
                    case "System.Data.SQL":
                        string _instance = String.Empty;
                        string _port = String.Empty;
                        string _server = list["Server"].Value;
                        if (_server.IndexOf("\\") > 0)
                        {
                            _instance = _server.Substring(_server.LastIndexOf("\\"));
                        }
                        if (_server.IndexOf(":")>0)
                        {
                            _port = _server.Substring(_server.LastIndexOf(":"));                            
                        }
                        if (!string.IsNullOrEmpty(_instance))
                        {
                            _port = _port.Replace(_instance, "");
                            _server = _server.Replace(_instance, "");
                        }
                        if (!string.IsNullOrEmpty(_port))
                        {
                            _server = _server.Replace(_port, "");
                        }
                        this.Port = _port.Replace(":","");
                        this.Server = _server.Replace ("http:\\","");                       
                        this.Instance_Name = _instance.Replace("\\","");
                        this.DataBaseName = list["Initial Catalog"].Value;
                        if (list.ContainsKey("Integrated Security"))
                        {
                            this.DataBaseLoginStyle = DataBaseLoginStyle.Integrated_Security;
                            this.UserID = "";
                            this.Password = "";
                        }
                        else
                        {
                            this.DataBaseLoginStyle = DataBaseLoginStyle.SqlServer_Identity;
                            this.UserID = list["User ID"].Value;
                            this.Password = list["Pwd"].Value;
                        }                       

                        this.Company = "Microsoft";
                        this.Version = "Sql Server 2008";

                        break;
                    case "System.Data.Sqlite":
                    case "System.Data.SQLite":
                        Data_Server = list["Data Source"].Value;
                        this.Server = Data_Server;
                        this.DataBaseName = Data_Server.Substring(Data_Server.LastIndexOf("\\") + 1);
                        this.Password = list.ContainsKey("Password") ? list["Password"].Value : "";
                        break;
                    case "System.Data.PostgreSql":
                        Data_Server = list["Server"].Value;
                        this.Server = Data_Server;                      
                        this.Port = list["Port"].Value;
                        this.Instance_Name = "";
                        this.DataBaseName = list["Database"].Value;
                        this.UserID = list["User Id"].Value;
                        this.Password = list["Password"].Value;  
                      
                        this.Company = "未知";
                        this.Version = "PostgreSql 11.23";

                        break;
                }
              
                list.Clear();               
            }
            else
            {
                //ConnectionString="Data Source=C:\Users\Administrator\Desktop\Ly.BDF\Ly.BDF\Ly.BDF.WebApp\App_Data\fasdb.db;Version=3;Password=4HxbajmTkLY=;UseUTF16Encoding=True;";
                //ConnectionString = "Server=192.168.0.2;Initial Catalog=LingyunDevelopFramework_Base;User ID=sa;Pwd=fineex.com;";
                string _connectionString = String.Empty;
                switch (this.ProviderName)
                {
                    case "System.Data.Sql":

                        _connectionString = "Server="+this.Server;
                        if (!string.IsNullOrEmpty(this.Port))
                        {
                            _connectionString += ":" + this.Port;
                        }
                        if (!string.IsNullOrEmpty(this.Instance_Name))
                        {
                            _connectionString += "\\"+this.Instance_Name;
                        }
                        _connectionString += ";";
                        _connectionString += "Initial Catalog="+this.DataBaseName+";";

                        if (this.DataBaseLoginStyle == DataBaseLoginStyle.Integrated_Security)
                        {
                            _connectionString += "Integrated Security=SSPI;";
                        }
                        else
                        {
                            _connectionString += "User ID="+this.UserID+";";
                            _connectionString += "Pwd="+this.Password+";";
                        }                       
                        
                        break;
                    case "System.Data.PostgreSql":

                        _connectionString = "Server="+this.Server+";";
                        _connectionString += "Port=" + this.Port + ";";                       
                        _connectionString += "Database=" + this.DataBaseName + ";";

                        _connectionString += "User ID="+this.UserID+";";
                        _connectionString += "Pwd=" + this.Password + ";";
                        _connectionString += "CommandTimeout=0;";
                        _connectionString += "ConnectionLifeTime=0;";

                        break;
                }
                ConnectionString = _connectionString;               
            }

            CreateKeyWords(ProviderName);

        }

        public object Clone()
        {
           return this.MemberwiseClone();
        }

        public void CreateKeyWords(string ProviderName)
        {
            this.Keywords = new List<Keyword>();
            this.Keywords.Add(new Keyword() { Text = "AS" });
            this.Keywords.Add(new Keyword() { Text = "AND" });
            this.Keywords.Add(new Keyword() { Text = "ASC" });
            this.Keywords.Add(new Keyword() { Text = "BETWEEN" });
            this.Keywords.Add(new Keyword() { Text = "SELECT" });
            this.Keywords.Add(new Keyword() { Text = "SELECT TOP",Description="只有SQL Server Access 数据库支持" });
            this.Keywords.Add(new Keyword() { Text = "SET" });
            this.Keywords.Add(new Keyword() { Text = "BY" });
            this.Keywords.Add(new Keyword() { Text = "CREATE" });
            this.Keywords.Add(new Keyword() { Text = "CREATE TABLE", Description = "创建表" });
            this.Keywords.Add(new Keyword() { Text = "CREATE VIEW", Description = "创建视图" });
            this.Keywords.Add(new Keyword() { Text = "COUNT", Description = "统计数量" });
            this.Keywords.Add(new Keyword() { Text = "DISTINCT" });
            this.Keywords.Add(new Keyword() { Text = "DELETE", Description = "删除数据" });
            this.Keywords.Add(new Keyword() { Text = "FROM" });
            this.Keywords.Add(new Keyword() { Text = "INSERT" });
            this.Keywords.Add(new Keyword() { Text = "WHERE" });
            this.Keywords.Add(new Keyword() { Text = "LIKE" });
            this.Keywords.Add(new Keyword() { Text = "LEFT JOIN", Description = "左连接语句" });
            this.Keywords.Add(new Keyword() { Text = "RIGHT JOIN", Description = "右连接语句" });
            this.Keywords.Add(new Keyword() { Text = "INTO" });
            this.Keywords.Add(new Keyword() { Text = "TOP" });
            this.Keywords.Add(new Keyword() { Text = "ON" });
            this.Keywords.Add(new Keyword() { Text = "HAVING" });
            this.Keywords.Add(new Keyword() { Text = "ORDER" });
            this.Keywords.Add(new Keyword() { Text = "ORDER BY" });
            this.Keywords.Add(new Keyword() { Text = "GROUP BY" });
            this.Keywords.Add(new Keyword() { Text = "GROUP" });
            this.Keywords.Add(new Keyword() { Text = "GO" });
            this.Keywords.Add(new Keyword() { Text = "OR" });           
            this.Keywords.Add(new Keyword() { Text = "UPDATE" });
            this.Keywords.Add(new Keyword() { Text = "DROP", Description = "删除结构如：drop table" });                     
            this.Keywords.Add(new Keyword() { Text = "DESC" });
            this.Keywords.Add(new Keyword() { Text = "INNER JOIN" });
            this.Keywords.Add(new Keyword() { Text = "LIMIT" });
        }

        public bool IsKeyWords(string input)
        {
            bool rvl = false;

            if (this.Keywords != null)
            {
                foreach (Keyword key in this.Keywords)
                {
                    if (key.Text.Equals(input, StringComparison.OrdinalIgnoreCase))
                    {
                        rvl = true;
                        break;
                    }
                }                
            }

            return rvl;
        }

        public bool IsFunctions(string input)
        {
            bool rvl = false;

            foreach (Function fun in this.Functions)
            {
                if (fun.Name.Equals(input, StringComparison.OrdinalIgnoreCase))
                {
                    rvl = true;
                    break;
                }
            }

            return rvl;
        }

    }
}
